﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Text;
using TomNet.Core.Options;
using TomNet.Exceptions;
using TomNet.Extensions;

namespace TomNet.AspNetCore.Identity
{
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 配置JWT验证
        /// </summary>
        public static IServiceCollection AddJwtAuthentication(this IServiceCollection services)
        {
            services.AddTransient<IPrincipal>(provider =>
            {
                IHttpContextAccessor accessor = provider.GetService<IHttpContextAccessor>();
                return accessor?.HttpContext?.User;
            });

            IConfiguration configuration = services.GetConfiguration();
            JwtOptions jwt = new JwtOptions();
            configuration.Bind("TomNet:Jwt", jwt);
            if (!jwt.Enabled)
            {
                return services;
            }
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,
                opts =>
                {
                    string secret = jwt.Secret;
                    if (secret.IsNullOrEmpty())
                    {
                        throw new TomNetException("配置文件中节点 TomNet:Jwt:Secret不能为空");
                    }

                    opts.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidIssuer = jwt.Issuer ?? "tomnet identity",
                        ValidAudience = jwt.Audience ?? "tomnet demo",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),

                        ValidateAudience = true,
                        ValidateIssuer = true,
                        RequireExpirationTime = true,
                        LifetimeValidator = (nbf, exp, token, param) => exp > DateTime.UtcNow,
                        ClockSkew = TimeSpan.FromSeconds(60),
                    };


                });
            return services;
        }

    }
}
